% Matlab script: mm1.m
% Proposito: Simula un modelo de cola con servidor simple del tipo
%			  M/M/1 con disciplina FIFO.
%			  Lee el archivo de entrada mm1.inp donde en el primer registro
%			  aparecen, separados por espacios: tiempo medio entre arribos, 
%			  tiempo medio de servicio y numero de clientes total procesados.
%			  La salida de la simulacion se da en dos archivos:
%			  mm1.out: Muestra valores estadisticos computados
%			  mm1.tim: Muestra la series de tiempo resultado de la simulacion
%			  
%			  Adaptado de "Simulation Modeling & Analysis", Law y Kelton.Proposito:     Simula una cola M/M/1
%
% Funciones utilizadas:
% arrive.m
% depart.m
% expon.m
% initialize.m
% report.m
% timing.m
% update_time_avg_stats.m
%
% Autor: Alejandro Diaz
% Declaracion de constantes y variables:
clear all

global Q_LIMIT;
global BUSY;
global IDLE;

global next_event_type;
global num_custs_delayed;
global time_limit;
global num_events;
global num_in_q;
global server_status;

num_custs_delayed = cell(1, 2);
num_in_q = cell(1, 2);
server_status = cell(1, 2);

global area_num_in_q;
global area_server_status;
global mean_arrival_1;
global service_1_params;
global service_2_params;
global time;
global time_arrival;
global time_last_event;
global time_next_event;
global total_of_delays;

area_num_in_q = cell(1, 2);
area_server_status = cell(1, 2);
time_arrival = cell(1, 2);
total_of_delays = cell(1, 2);

global countE;
global countR;


%
Q_LIMIT = 100;
BUSY    = 1;
IDLE    = 0;

% Abre los archivos I/O
inpfile = fopen('mm1.inp','r');
global outfile;
outfile = fopen('mm1.out','w');
timfile = fopen('mm1.tim','w');

% Especifica el numero de eventos
%Entrada, salida de cola 1 a cola 2, realimentacion a cola 1, salida del
%sistema
num_events = 4;

% Lee el archivo de entrada
xdata = fscanf(inpfile,'%f %f %f %f %f %f',[1 6]);
mean_arrival_1 = xdata(1);
service_1_params(1) = xdata(2);
service_1_params(2) = xdata(3);
service_2_params(1) = xdata(4);
service_2_params(2) = xdata(5);
time_limit = xdata(6);
 

% Escribe los encabezados de los reportes y parametros de entrada
fprintf(outfile,'Sistema de colas de servidores\n\n');
fprintf(outfile,'Tiempo medio entre arribos %11.3f minutos\n\n',mean_arrival_1);
fprintf(outfile,'Tiempo medio de servicio_1 %11.3f a %11.3f minutos\n\n',service_1_params(1), service_1_params(2));
fprintf(outfile,'Tiempo medio de servicio_2 %11.3f a %11.3f minutos\n\n',service_2_params(1), service_2_params(2));
fprintf(outfile,'Tiempo de espera %14d\n\n', time_limit);

fprintf(timfile,'Series de tiempo producidas\n');
fprintf(timfile,'time\n');
fprintf(timfile,'longitud de la cola 1\n');
fprintf(timfile,'ocupacion del servidor 1 (OCUPADO=1,LIBRE=0)\n');
fprintf(timfile,'longitud de la cola 2\n');
fprintf(timfile,'ocupacion del servidor 2 (OCUPADO=1,LIBRE=0)\n');

% Inicializa la simulacion
initialize();

% Corre la simulacion
while ( time < time_limit )
	fprintf(timfile, '%16.3f %d %d %d %d Event %d\n',time,num_in_q{1},server_status{1},num_in_q{2},server_status{2}, next_event_type);
	% Determina el proximo evento
	timing();
	
	% Actualiza los acumuladores estadisticos de tiempos medios
	update_time_avg_stats();
	
	% Invoca al evento apropiado
	switch (next_event_type)
		case 1
			arrive();
		case 2
			depart_from_queue_1();
        case 3
            depart_from_queue_2();
        case 4
            depart_from_queue_2();
    end
            
end

% Invoca al generador de reportes y fin de la simulacion
report(outfile);
fclose(inpfile);
fclose(outfile);
fclose(timfile);